﻿using Beryl.OrderControllers.DBUpdate;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;

namespace Beryl.OrderControllers.DataStructural
{
    public class reWorkStructural
    {
        private static reWorkStructural instance = null;
        private static readonly object uniqueLock = new object();
        public static reWorkStructural Instance
        {
            get
            {
                lock (uniqueLock)
                {
                    if (instance == null)
                    {
                        instance = new reWorkStructural();
                    }
                }
                return instance;
            }
        }
        public reWorkStructural() { }

        #region
        //数据结构化
        public Dictionary<string,DataRow> getPlanAndRework(DataRow[] PlanAndSorderRow)
        {
           
            var PlanAndReworkObj = new Dictionary<string, DataRow>();
            for (int i = 0; i < PlanAndSorderRow.Length; i++)
            {
                string cReworkNo = PlanAndSorderRow[i]["cReworkNo"].ToString();
                if (!PlanAndReworkObj.ContainsKey(cReworkNo))
                {
                    PlanAndReworkObj.Add(cReworkNo, null);
                }
                PlanAndReworkObj[cReworkNo] = PlanAndSorderRow[i];
            }
            return PlanAndReworkObj;
        }

        public Dictionary<string, Dictionary<string, Dictionary<string, List<DataRow>>>> getRework(DataRow[] ReworkRow)
        {
            var reworkObj = new Dictionary<string, Dictionary<string, Dictionary<string, List<DataRow>>>>();
            for (int i = 0; i < ReworkRow.Length; i++)
            {
                string cReworkNo = ReworkRow[i]["cReworkNo"].ToString();
                if (!reworkObj.ContainsKey(cReworkNo))
                {
                    reworkObj.Add(cReworkNo, new Dictionary<string, Dictionary<string, List<DataRow>>>());
                }
                string cMatNo = ReworkRow[i]["cMatNo"].ToString();
                if (!reworkObj[cReworkNo].ContainsKey(cMatNo))
                {
                    reworkObj[cReworkNo].Add(cMatNo,new Dictionary<string, List<DataRow>>());
                }
                string cMatandResNo = ReworkRow[i]["cMatandResNo"].ToString();
                
                if (!reworkObj[cReworkNo][cMatNo].ContainsKey(cMatandResNo))
                {
                    reworkObj[cReworkNo][cMatNo].Add(cMatandResNo,new List<DataRow>());
                }
                reworkObj[cReworkNo][cMatNo][cMatandResNo].Add(ReworkRow[i]);
            }
            return reworkObj;
        }

        public Dictionary<string, List<DataRow>> getMatData(DataRow[] MatDataRow)
        {
            Dictionary<string, List<DataRow>> MatDataObj = new Dictionary<string, List<DataRow>>();
            List<DataRow> MatDataRows = new List<DataRow>();
            for (int i = 0; i < MatDataRow.Length; i++)
            {
                string cMatNo = MatDataRow[i]["cMatNo"].ToString();
                if (!MatDataObj.ContainsKey(cMatNo))
                {
                    MatDataRows = new List<DataRow>();
                    MatDataObj.Add(cMatNo, null);
                }
                MatDataRows.Add(MatDataRow[i]);
                MatDataObj[cMatNo] = MatDataRows;
            }
            return MatDataObj;
        }

        public Dictionary<string, Dictionary<string, string>> getPlanOrder(DataRow[] planOrderRow)
        {
            Dictionary<string, Dictionary<string, string>> planOrderObj = new Dictionary<string, Dictionary<string, string>>();
            Dictionary<string, string> valuePairs = new Dictionary<string, string>();
            List<string> dataRows = new List<string>();
            for (int i = 0; i < planOrderRow.Length; i++)
            {
                string cPOrderNo = planOrderRow[i]["cPOrderNo"].ToString();
                if (!planOrderObj.ContainsKey(cPOrderNo))
                {
                    dataRows = new List<string>();
                    valuePairs = new Dictionary<string, string>();
                    planOrderObj.Add(cPOrderNo, null);
                    valuePairs.Add("cMatNo", planOrderRow[i]["cMatNo"].ToString());
                    valuePairs.Add("dPlanQty", planOrderRow[i]["dPlanQty"].ToString());
                    valuePairs.Add("dPlanQty1", planOrderRow[i]["dPlanQty1"].ToString());
                    valuePairs.Add("dDeliveryDate", planOrderRow[i]["dDeliveryDate"].ToString());
                    valuePairs.Add("cProductDepNo", planOrderRow[i]["cProductDepNo"].ToString());
                    valuePairs.Add("cReworkFlag", planOrderRow[i]["cReworkFlag"].ToString());      //重工单标识
                    valuePairs.Add("cOFlag", "");           //插单标识
                    valuePairs.Add("cBigBegProDate", planOrderRow[i]["cBigBegProDate"].ToString()); //大批量订单开始生产日期
                    valuePairs.Add("iBatchMult", "");          //生产批量倍数
                    valuePairs.Add("MotypeCode", planOrderRow[i]["MotypeCode"].ToString());
                    valuePairs.Add("dProBatch", planOrderRow[i]["dProBatch"].ToString());
                }
                dataRows.Add(CommonMethod.Instance.dataRowToJson(planOrderRow[i]));
                string json = CommonMethod.Instance.ToJsonString(dataRows);
                if (!valuePairs.ContainsKey("json"))
                {
                    valuePairs.Add("json", json);
                }
                else
                {
                    valuePairs.Remove("json");
                    valuePairs.Add("json", json);
                }
                planOrderObj[cPOrderNo] = valuePairs;
            }
            return planOrderObj;
        }

        public Dictionary<string, Dictionary<string, DataRow>> getReworkRouting(DataRow[] ReworkRouting)
        {
            var ReworkRoutingObj = new Dictionary<string, Dictionary<string, DataRow>>();

            for (int i = 0; i < ReworkRouting.Length; i++)
            {
                string cPRoutingNo = ReworkRouting[i]["cPRoutingNo"].ToString();
                if (!ReworkRoutingObj.ContainsKey(cPRoutingNo))
                {
                   ReworkRoutingObj.Add(cPRoutingNo, new Dictionary<string, DataRow>());
                }
                string cOperationNo = ReworkRouting[i]["cOperationNo"].ToString();
                if (!ReworkRoutingObj[cPRoutingNo].ContainsKey(cOperationNo))
                {
                    ReworkRoutingObj[cPRoutingNo].Add(cOperationNo,null);
                }
                ReworkRoutingObj[cPRoutingNo][cOperationNo] = ReworkRouting[i];
            }
            return ReworkRoutingObj;
        }
        #endregion

        public Dictionary<string, Dictionary<string, Dictionary<string, string>>> TraverseSource(string cPOrderNo, Dictionary<string, Dictionary<string, string>> planOrderObj, string batchNum,
           Dictionary<string, Dictionary<string, Dictionary<string, string>>> proOrderObj, string proLotOrderNo, string loginUser, int serialNum, string cMOLotNo, 
           out Dictionary<string, Dictionary<string, string>> planOrderObjPara)
        {
            try
            {
                Dictionary<string, string> keys = null;
                List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
                float ddQty = 0;
                // 生产订单编号
                string proOrderNo = cPOrderNo;
                // 生产部门
                string cProductDepNo = planOrderObj[cPOrderNo]["cProductDepNo"];
                //订单类别
                string MotypeCode = planOrderObj[cPOrderNo]["MotypeCode"];
                string str = "";
                if (cProductDepNo == "Z61")
                {
                    str = MotypeCode;
                }
                else if (cProductDepNo == "Z21")
                {
                    str = MotypeCode;
                }
                // 交货期
                string dDeliveryDate = planOrderObj[cPOrderNo]["dDeliveryDate"];
                string cReworkFlag = "";
                string cOFlag = "";
                string cBigBegProDate = "";
                float iBatchMult = 0;

                if (planOrderObj[cPOrderNo].ContainsKey("json"))
                {
                    string json = planOrderObj[cPOrderNo]["json"];
                    Newtonsoft.Json.Linq.JArray jsonArr = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(json);
                    if (jsonArr.Count > 0)
                    {
                        var jsonArr1 = jsonArr[0].ToString();
                        Newtonsoft.Json.Linq.JArray plan = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(jsonArr1);
                        //重工单标识
                        cReworkFlag = plan[8].ToString();
                        //插单标识
                        cOFlag = "";
                        //大批量订单开始生产日期
                        cBigBegProDate = plan[9].ToString();
                        //生产批量倍数
                        iBatchMult = 0;
                    }
                }
                else
                {
                    //重工单标识
                    cReworkFlag = planOrderObj[cPOrderNo]["cReworkFlag"];
                    //插单标识
                    cOFlag = "";
                    //大批量订单开始生产日期
                    cBigBegProDate = planOrderObj[cPOrderNo]["cBigBegProDate"];
                    //生产批量倍数
                    iBatchMult = 0;
                }
                // // 物料编号
                string cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                // 配比
                string cCombination = "";
                // 条码值
                string cBarCode = "WO-" + proOrderNo + str + "-" + serialNum;
                string ccSourceNo = "";
                ddQty = float.Parse(planOrderObj[cPOrderNo]["dPlanQty1"]);
                // 拆批大小<=需求
                keys = new Dictionary<string, string>();
                if (float.Parse(batchNum) < ddQty)
                {
                    // 物料编号
                    cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                    // 成品（加工批次）
                    keys.Add("loginUser", loginUser);
                    keys.Add("cSourceNo", ccSourceNo);
                    keys.Add("cMatNo", cMatNo);
                    keys.Add("Num", batchNum);
                    keys.Add("cPOrderNo", cPOrderNo);
                    keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                    keys.Add("cReworkFlag", cReworkFlag);
                    keys.Add("cOFlag", cOFlag);
                    keys.Add("cCombination", cCombination);
                    keys.Add("cBigBegProDate", cBigBegProDate);
                    keys.Add("iBatchMult", iBatchMult.ToString());
                    keys.Add("cBarCode", cBarCode);
                    keys.Add("cBatchNumber", cMOLotNo);
                }
                else if (float.Parse(batchNum) == ddQty)
                {
                    // 物料编号
                    cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                    // 成品（加工批次）
                    keys.Add("loginUser", loginUser);
                    keys.Add("cSourceNo", ccSourceNo);
                    keys.Add("cMatNo", cMatNo);
                    keys.Add("Num", batchNum);
                    keys.Add("cPOrderNo", cPOrderNo);
                    keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                    keys.Add("cReworkFlag", cReworkFlag);
                    keys.Add("cOFlag", cOFlag);
                    keys.Add("cCombination", cCombination);
                    keys.Add("cBigBegProDate", cBigBegProDate);
                    keys.Add("iBatchMult", iBatchMult.ToString());
                    keys.Add("cBarCode", cBarCode);
                    keys.Add("cBatchNumber", cMOLotNo);
                }
                else
                {
                    // 物料编号
                    cMatNo = planOrderObj[cPOrderNo]["cMatNo"];
                    // 成品（加工批次）
                    keys.Add("loginUser", loginUser);
                    keys.Add("cSourceNo", ccSourceNo);
                    keys.Add("cMatNo", cMatNo);
                    keys.Add("Num", ddQty.ToString());
                    keys.Add("cPOrderNo", cPOrderNo);
                    keys.Add("dPlanQty", planOrderObj[cPOrderNo]["dPlanQty"]);
                    keys.Add("cReworkFlag", cReworkFlag);
                    keys.Add("cOFlag", cOFlag);
                    keys.Add("cCombination", cCombination);
                    keys.Add("cBigBegProDate", cBigBegProDate);
                    keys.Add("iBatchMult", iBatchMult.ToString());
                    keys.Add("cBarCode", cBarCode);
                    keys.Add("cBatchNumber", cMOLotNo);
                }
                planOrderObj[cPOrderNo].Remove("json");

                if (!proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson"))
                {
                    list.Add(keys);
                    string listJson = CommonMethod.Instance.ToJsonString(list);
                    proOrderObj[proOrderNo][proLotOrderNo].Add("listJson", listJson);
                }
                else
                {
                    string json = proOrderObj[proOrderNo][proLotOrderNo]["listJson"];
                    List<Dictionary<string, string>> people = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(json);
                    people.Add(keys);
                    string listJson1 = CommonMethod.Instance.ToJsonString(people);
                    proOrderObj[proOrderNo][proLotOrderNo]["listJson"] = listJson1;
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            planOrderObjPara = planOrderObj;
            return proOrderObj;
        }

        public Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> getBatchMatReworkQty(Dictionary<string, Dictionary<string, Dictionary<string, string>>> proOrderObj,
          DataRow[] PlanAndSorder, DataRow[] Rework)
        {
            var proLotMatQtyObj = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>();
            try
            {
                var planOrderObj = new Dictionary<string, DataRow>();
                var reworkObj = new Dictionary<string, Dictionary<string, Dictionary<string, DataRow>>>();

                for (int i = 0; i < PlanAndSorder.Length; i++)
                {
                    string cPOrderNo = PlanAndSorder[i]["cPOrderNo"].ToString();
                    if (!planOrderObj.ContainsKey(cPOrderNo))
                    {
                        planOrderObj.Add(cPOrderNo, null);
                    }
                    planOrderObj[cPOrderNo] = PlanAndSorder[i];
                }

                for (int i = 0; i < Rework.Length; i++)
                {
                    string cReworkNo = Rework[i]["cReworkNo"].ToString();
                    if (!reworkObj.ContainsKey(cReworkNo))
                    {
                        reworkObj.Add(cReworkNo, new Dictionary<string, Dictionary<string, DataRow>>());
                    }
                    string cMatNo = Rework[i]["cMatNo"].ToString();
                    if (!reworkObj[cReworkNo].ContainsKey(cMatNo))
                    {
                        reworkObj[cReworkNo].Add(cMatNo, new Dictionary<string, DataRow>());
                    }
                    string cMatandResNo = Rework[i]["cMatandResNo"].ToString();
                    if (!reworkObj[cReworkNo][cMatNo].ContainsKey(cMatandResNo))
                    {
                        reworkObj[cReworkNo][cMatNo].Add(cMatandResNo, null);
                    }
                    reworkObj[cReworkNo][cMatNo][cMatandResNo] = Rework[i];
                }
                float length = 0;
                // 遍历生产订单
                foreach (var proOrderNo in proOrderObj.Keys)
                {
                    string cReworkNo = planOrderObj[proOrderNo]["cReworkNo"].ToString();
                    // 遍历生产批次
                    foreach (var proLotOrderNo in proOrderObj[proOrderNo].Keys)
                    {
                        if (!proLotMatQtyObj.ContainsKey(proLotOrderNo))
                        {
                            proLotMatQtyObj.Add(proLotOrderNo, new Dictionary<string, Dictionary<string, Dictionary<string, string>>>());
                        }
                        if (proOrderObj[proOrderNo][proLotOrderNo].ContainsKey("listJson"))
                        {
                            string json = proOrderObj[proOrderNo][proLotOrderNo]["listJson"];
                            Newtonsoft.Json.Linq.JArray jArray = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(json);
                            for (int i = 0; i < jArray.Count; i++)
                            {
                                string cMatNo = "";
                                string cMatNo1 = jArray[i]["cMatNo"].ToString();
                                foreach (var matNo in reworkObj[cReworkNo].Keys)
                                {
                                    cMatNo = matNo;
                                }
                                if (cMatNo != cMatNo1)
                                {
                                    continue;
                                }
                                if (!proLotMatQtyObj[proLotOrderNo].ContainsKey(cMatNo))
                                {
                                    proLotMatQtyObj[proLotOrderNo].Add(cMatNo, new Dictionary<string, Dictionary<string, string>>());
                                }
                                //拆批量
                                string Num = jArray[i]["Num"].ToString();
                                string batchNum = proOrderObj[proOrderNo][proLotOrderNo]["batchNum"].ToString();
                                string cBatchNumber = jArray[i]["cBatchNumber"].ToString();
                                if (cBatchNumber == null)
                                {
                                    cBatchNumber = "";
                                }
                                // 钉卷需求数量
                                string ddQty = planOrderObj[proOrderNo]["dPlanQty1"].ToString();
                                float length1 = 0;
                                foreach (var cMatandResNo in reworkObj[cReworkNo][cMatNo].Keys)
                                {
                                    string cProRoutingNo = reworkObj[cReworkNo][cMatNo][cMatandResNo]["cProRoutingNo"].ToString();
                                    // 生产一个成品需要单位原材料量
                                    float cMatQty_Unit = 1;
                                    if (cMatandResNo.IndexOf('C') != -1)
                                    {
                                        cMatQty_Unit = 1;
                                    }
                                    else
                                    {
                                        // 生产订单需求量
                                        string dPlanQty = reworkObj[cReworkNo][cMatNo][cMatandResNo]["dMatQty"].ToString();
                                        // 生产一个成品需要单位原材料量
                                        cMatQty_Unit = float.Parse(dPlanQty) / float.Parse(ddQty);
                                        cBatchNumber = "";
                                    }
                                   
                                    if (!proLotMatQtyObj[proLotOrderNo][cMatNo].ContainsKey(cMatandResNo))
                                    {
                                        proLotMatQtyObj[proLotOrderNo][cMatNo].Add(cMatandResNo, new Dictionary<string, string>());
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cMatTotal", (cMatQty_Unit * float.Parse(batchNum)).ToString());
                                    }
                                    else
                                    {
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].TryGetValue("cMatTotal", out string cMat);
                                        float sum = cMatQty_Unit * float.Parse(batchNum);
                                        float total = float.Parse(cMat);
                                        total = total + sum;
                                        proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo]["cMatTotal"] = total.ToString();
                                    }
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOrderType", "4");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOperationNo", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOperationName", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cOpSeq", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cInOutType", "input");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cMatandResName", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cMatandResType", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("dWidth", "0");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("dLength", "1");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cSpecifution", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cUnit", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCapacityLow", "0");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCapacityUp", "0");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCapacity", "0");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cBomid", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cSortSeq", "0");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cCateNo", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("dVoltage", "0");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("Unit", "");
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cBatchNumber", cBatchNumber);
                                    proLotMatQtyObj[proLotOrderNo][cMatNo][cMatandResNo].Add("cProRoutingNo", cProRoutingNo);
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("错误");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return proLotMatQtyObj;
        }

        //获取工艺路线
        public Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> getProRouting(
            Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>> proLotMatQtyObj,
            Dictionary<string, Dictionary<string, DataRow>> ReworkRoutingObj)
        {
            var proRoutingObj = new Dictionary<string, Dictionary<string, Dictionary<string, Dictionary<string, string>>>>();
            try
            {
                foreach (var cMOLotNo in proLotMatQtyObj.Keys)
                {
                    string cOrderNo = cMOLotNo;
                    if (cMOLotNo != "length")
                    {
                        if (!proRoutingObj.ContainsKey(cMOLotNo))
                        {
                            proRoutingObj.Add(cOrderNo, new Dictionary<string, Dictionary<string, Dictionary<string, string>>>());
                        }
                        foreach (var cMatNo in proLotMatQtyObj[cMOLotNo].Keys)
                        {
                            float dTransferTime = 0;
                            string cProRoutingNo = "";
                            if (!proRoutingObj[cOrderNo].ContainsKey(cMatNo))
                            {
                                proRoutingObj[cOrderNo].Add(cMatNo, new Dictionary<string, Dictionary<string, string>>());
                            }
                            foreach (var num in proLotMatQtyObj[cMOLotNo][cMatNo].Keys)
                            {
                                if (num != "length")
                                {
                                    cProRoutingNo = proLotMatQtyObj[cMOLotNo][cMatNo][num]["cProRoutingNo"];
                                    continue;
                                }
                            }
                            if(ReworkRoutingObj.ContainsKey(cProRoutingNo))
                            {

                                foreach (var cOperationNo in ReworkRoutingObj[cProRoutingNo].Keys)
                                {
                                    proRoutingObj[cOrderNo][cMatNo].Add(cOperationNo,new Dictionary<string, string>());
                                    string cOperationName = ReworkRoutingObj[cProRoutingNo][cOperationNo]["cOperationName"].ToString();
                                    string cOpSeq = ReworkRoutingObj[cProRoutingNo][cOperationNo]["cOpSeq"].ToString();
                                    proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("cOrderType","4");
                                    proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("cOperationName", cOperationName);
                                    proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("cOpSeq", cOpSeq);
                                    proRoutingObj[cOrderNo][cMatNo][cOperationNo].Add("dTransferTime", dTransferTime.ToString());
                                }
                            } 
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
            return proRoutingObj;
        }
    }
}